<template>
  <el-container class="user-page" v-if="!showOrgChart">
    <el-aside width="260px">
      <el-container>
        <el-header>
          <el-button-group style="width: 100%">
            <el-button :type="switchType.dept ? 'primary' : ''" icon="el-icon-user" @click="changeType('dept')" style="width: 50%">按部门</el-button>
            <el-button :type="switchType.role ? 'primary' : ''" icon="el-icon-set-up" @click.stop="changeType('role')" style="width: 50%">按角色</el-button>
          </el-button-group>
        </el-header>
        <el-main class="nopadding">
          <template v-if="switchType.dept">
            <el-tree ref="depts" class="menu" node-key="id" default-expand-all :data="tree.depts" :current-node-key="''" :highlight-current="true" :expand-on-click-node="false" @node-click="deptClick" v-loading="loading.dept" style="padding: 10px"> </el-tree>
          </template>
          <template v-else>
            <el-tree ref="roles" class="menu" node-key="roleId" default-expand-all :data="tree.roles" :highlight-current="true" @node-click="roleClick" v-loading="loading.role"  style="padding: 10px">
              <template #default="{ node, data }">
                <span class="custom-tree-node">
                  <span class="label">
                    {{ node.label }}
                  </span>
                  <span class="do" v-if="data.id != ''">
                    <el-button-group>
                      <el-button icon="el-icon-edit" size="small" @click.stop="roleModify(data.id)"></el-button>
                      <el-button icon="el-icon-delete" size="small" @click.stop="roleDelete(node, data)"></el-button>
                    </el-button-group>
                  </span>
                </span>
              </template>
            </el-tree>
          </template>
        </el-main>
        <el-footer style="height: 51px">
          <el-button-group style="width: 100%">
            <el-button type="primary" size="small" icon="el-icon-user" @click="deptBtn" style="width: 50%" :disabled="switchType.role">部门管理</el-button>
            <el-button type="success" size="small" icon="el-icon-set-up" @click.stop="roleBtn" style="width: 50%" :disabled="switchType.dept">新增角色</el-button>
          </el-button-group>
        </el-footer>
      </el-container>
    </el-aside>
    <el-container>
      <el-header>
        <div class="left-panel">
          <el-button type="primary" icon="el-icon-plus" @click="add" v-auth="'system:user:add'"></el-button>
          <el-button type="danger" plain icon="el-icon-delete" :disabled="selection.length == 0" @click="batchDelete" v-auth="'system:user:remove'"></el-button>
          <!-- <el-button type="primary" plain :disabled="selection.length == 0">分配角色</el-button> -->
          <el-button type="primary" @click="resetUserPwd" plain :disabled="selection.length != 1" v-auth="'system:user:resetPwd'">密码重置</el-button>
        </div>
        <div class="right-panel">
          <div class="right-panel-search">
            <el-input ref="searchInput" v-model="search.keyword" minlength="1" maxlength="20" placeholder="请输入关键字" clearable>
              <template #prepend>
                <el-select v-model="search.type" placeholder="请选择..." style="width: 100px">
                  <el-option label="账号" value="userName"></el-option>
                  <el-option label="姓名" value="nickName"></el-option>
                  <el-option label="手机" value="phonenumber"></el-option>
                </el-select>
              </template>
            </el-input>
            <el-button type="primary" icon="el-icon-search" @click="btnSearch"></el-button>
            <el-button type="text" icon="el-icon-menu" @click="changeOrgChart">组织架构</el-button>
          </div>
        </div>
      </el-header>
      <el-main class="nopadding">
        <jdTable ref="table" :apiObj="apiObj" size="large" @selection-change="selectionChange" :params="params" stripe remoteSort remoteFilter>
          <el-table-column type="selection" width="50"></el-table-column>
          <!-- <el-table-column label="头像" width="80">
            <template #default="scope">
              <el-avatar :src="scope.row.avatar" size="small"></el-avatar>
            </template>
          </el-table-column> -->
          <el-table-column label="账号" prop="userName" min-width="150" fixed="left"></el-table-column>
          <el-table-column label="手机号" prop="phonenumber" min-width="150" fixed="left"></el-table-column>
          <el-table-column label="姓名" prop="nickName" min-width="150"></el-table-column>
          <el-table-column label="角色" prop="roleId"></el-table-column>
          <el-table-column label="所在部门" prop="deptId" align="center" min-width="150">
            <template #default="scope">
              {{ groupMap[scope.row.deptId] }}
            </template>
          </el-table-column>
          <el-table-column label="状态" prop="status" width="150" align="center">
            <template #default="scope">
              <el-switch @update:modelValue="changeUserStatus($event, scope.row)" :model-value="scope.row.status" :disabled="scope.row.admin" active-value="0" inactive-value="1" />
            </template>
          </el-table-column>
          <el-table-column label="操作" fixed="right" align="center" width="150">
            <template #default="scope">
              <el-button-group>
                <el-button text type="primary" @click="handleUserModify(scope.row, scope.$index)" v-auth="'system:user:edit'" class="button" :disabled="scope.row.admin">编辑</el-button>
                <el-popconfirm title="确定要删除吗？" @confirm="handleUserDelete(scope.row, scope.$index)">
                  <template #reference>
                    <el-button text type="primary" v-auth="'system:user:remove'" class="button" :disabled="scope.row.admin">删除</el-button>
                  </template>
                </el-popconfirm>
              </el-button-group>
            </template>
          </el-table-column>
        </jdTable>
      </el-main>
    </el-container>
  </el-container>
  <el-container class="user-page" v-else>
    <el-main>
      <div class="orgChart">
        <el-button type="text" icon="el-icon-close" @click="changeOrgChart" class="close">关闭架构</el-button>
        <vue3-tree-org
          :data="tree.depts[0]"
          center
          :horizontal="horizontal"
          :collapsable="collapsable"
          :label-style="style"
          :scalable="scalable"
          :only-one-node="onlyOneNode"
          :clone-node-drag="cloneNodeDrag"
          :before-drag-end="beforeDragEnd"
          :toolBar="toolBar"
          @on-node-click="onDeptClick"
        />
      </div>
    </el-main>
  </el-container>

  <save-dialog v-if="dialog.save" ref="saveDialog" :roles="dialog.roles" @success="handleSuccess" @closed="dialog.save = false"></save-dialog>
  <permission-dialog v-if="dialog.permission" ref="permissionDialog" @closed="dialog.permission = false"></permission-dialog>
</template>

<script>
import saveDialog from "./save"
import permissionDialog from "../role/permission"
import { permissionAll } from "@/utils/permission"
import tool from "@/utils/tool"
import PinYin from "js-pinyin"

export default {
  name: "user",
  components: {
    saveDialog,
    permissionDialog
  },
  data() {
    return {
      switchType: {
        dept: true,
        role: false
      },
      loading: {
        dept: false,
        role: false
      },
      tree: {
        depts: [],
        roles: []
      },
      showOrgChart: false,
      showRolesloading: false,
      showGrouploading: false,

      dialog: {
        roles: [],
        save: false,
        permission: false,
        reset: false
      },
      groupFilterText: "",
      group: [],
      apiObj: this.$API.system.user.list,
      params: {},
      selection: [],
      search: {
        type: "userName",
        keyword: ""
      },

      depts: [],
      roles: [],
      horizontal: false,
      collapsable: false,
      onlyOneNode: false,
      expandAll: true,
      scalable: true,
      toolBar: {
        scale: false, restore: true, expand: true, zoom: true, fullscreen: true, 
      },
      style: {
        background: "#409EFF",
        color: "#FFFFFF",
        cursor: "pointer"
      },
    }
  },
  mounted() {
    // 部门列表
    this.getDepts()
    // 角色列表
    this.getRoles()
  },
  computed: {
    // todo 部门映射表 后面看接口有没有提供
    groupMap() {
      function deepForEach(arr, map = {}) {
        arr.forEach((item) => {
          if (Array.isArray(item.children) && item.children.length > 0) {
            deepForEach(item.children, map)
          }
          map[item.id] = item.label
        })
        return map
      }
      const result = deepForEach(this.tree.depts)
      return result
    }
  },
  methods: {
    // 显示部门架构
    changeOrgChart(){
      this.showOrgChart=!this.showOrgChart;
    },
    // 按部门、按角色筛选数据
    changeType(val) {
      if (val == "dept") {
        this.apiObj = this.$API.system.user.list
        this.switchType.dept = true
        this.switchType.role = false
      } else {
        this.apiObj = this.$API.system.user.roleList
        this.switchType.dept = false
        this.switchType.role = true
      }
    },
    // 加载部门列表
    async getDepts() {
      this.loading.dept = true
      var res = await this.$API.system.dept.tree.get()
      if (res.code == 200) {
        this.tree.depts = res.data
        this.loading.dept = false
      }
    },
    // 部门树点击事件
    deptClick(data) {
      var params = {
        deptId: data.id
      }
      this.$refs.table.reload(params)
    },
    // 部门点击事件
    onDeptClick(e,data){
      this.showOrgChart = false
      this.$nextTick(()=>{
        var params = {
          deptId: data.id
        }
        this.$refs.table.reload(params)
      })
    },
    // 部门管理
    deptBtn() {
      this.$router.push("/system/dept")
    },
    // 加载角色列表
    async getRoles() {
      this.loading.role = true
      let params = {
        roleType: 0
      }
      var res = await this.$API.system.role.list.get(params)
      if (res.code == 200) {
        var roleList = res.data.rows.map((row) => {
          return {
            label: row.roleName,
            id: row.roleId
          }
        })
        this.dialog.roles = roleList
        this.tree.roles = [...roleList];
        var allNode ={label: '所有角色', id: ''}
        this.tree.roles.unshift(allNode);

        this.loading.role = false
      }
    },
    // 角色树点击事件
    roleClick(data) {
      console.log(data)
      var params = {
        roleId: data.id
      }
      this.$refs.table.reload(params)
    },
    // 角色管理
    async roleBtn() {
      this.$prompt("角色名称", "新建角色", {
        inputPlaceholder: "请输入一个方便识别的角色名称",
        inputPattern: /\S/,
        inputErrorMessage: "角色名称不能为空"
      }).then(async ({ value }) => {
        // 获取拼音首字母
        PinYin.setOptions({ checkPolyphone: false, charCase: 0 })
        var roleKey = PinYin.getCamelChars(value)

        var data = {
          roleName: value,
          roleKey: roleKey,
          roleType: "0"
        }
        var res = await this.$API.system.role.saveRole.post(data);
        if(res.code == 200){
          console.log(res)
          // 将分组名称加入到目录树中
          this.$refs.roles.append({
            id: res.data,
            label: data.roleName
          });
          this.$message.success("操作成功")
        } else {
          this.$alert(res.msg, "提示", { type: "error" })
        }
      })
    },
    // 角色权限设置
    roleModify(roleId){
      this.dialog.permission = true;
      this.permissionBtn = true
      this.$nextTick(() => {
        this.$refs.permissionDialog.open(roleId)
      })
    },
    // 角色删除
    async roleDelete(node, data) {
      this.$confirm(`确认要删除该角色吗？`, "提示", {
        type: "warning",
        confirmButtonText: "删除",
        confirmButtonClass: "el-button--danger"
      }).then(async () => {
        var res = await this.$API.system.role.delRole.delete(data.id)
        if (res.code == 200) {
          this.$refs.table.refresh()
          this.$message.success("删除成功")
          let deleteNode = this.$refs.roles.getNode(node)
          this.$refs.roles.remove(deleteNode)
        } else {
          this.$alert(res.msg, "提示", { type: "error" })
        }
      })
    },
    //添加
    add() {
      this.dialog.save = true
      this.roles.filter((item) => {
        return item.label != "所有角色"
      })

      this.$nextTick(() => {
        this.$refs.saveDialog.open()
      })
    },
    // 编辑用户
    async handleUserModify(row) {
      let res = await this.$API.system.user.getUser.get(row.userId)
      if (res.code == 200) {
        if (res.roleIds != null) {
          res.data.roleIds = res.roleIds[0]
        }
        this.dialog.save = true

        this.$nextTick(() => {
          this.$refs.saveDialog.open("edit").setData(res.data)
        })
      }
    },
    // 删除用户
    async handleUserDelete(row) {
      var res = await this.$API.system.user.delUser.delete(row.userId)
      if (res.code == 200) {
        this.$refs.table.refresh()
        this.$message.success("删除成功")
      } else {
        this.$alert(res.msg, "提示", { type: "error" })
      }
    },
    // 改用用户状态
    async changeUserStatus(value, userInfo) {
      let permissions = permissionAll() || tool.data.get("PERMISSIONS").some((v) => v === "system:user:edit")
      if (permissions) {
        const oldStatus = userInfo.status
        userInfo.status = value
        const res = await this.$API.system.user.changeUserStatus.put(userInfo.userId, userInfo.status)
        if (res.code == 200 || res.code == 0) {
          this.$message.success(res.msg)
        } else {
          this.$message.error(res.msg)
          userInfo.status = oldStatus
        }
      }
    },
    // 重置用户密码
    async resetUserPwd() {
      this.$confirm(`确定要重置该用户的登录密码？`, "提示", {
        type: "warning"
      }).then(async () => {
        const loading = this.$loading()
        var res = await this.$API.system.user.resetUserPwd.put(this.selection[0].userId, "")
        if (res.code == 200) {
          loading.close()
          this.$notify({
            title: "操作成功",
            message: "密码重置成功，新的密码为：" + res.msg,
            type: "success"
          })
        } else {
          loading.close()
          this.$alert(res.msg, "提示", { type: "error" })
        }
      })
    },
    // 多项删除
    async batchDelete() {
      this.$confirm(`确定删除选中的 ${this.selection.length} 项吗？`, "提示", {
        type: "warning"
      })
        .then(async () => {
          const loading = this.$loading()
          let ids = this.selection.map((item) => item.userId)
          var res = await this.$API.system.user.delUser.delete(ids)
          if (res.code == 200) {
            //这里选择刷新整个表格 OR 插入/编辑现有表格数据
            this.$refs.table.getData()
            loading.close()
            this.$message.success("删除成功")
          } else {
            loading.close()
            this.$alert(res.msg, "提示", { type: "error" })
          }
        })
        .catch(() => {})
    },
    //表格选择后回调事件
    selectionChange(selection) {
      this.selection = selection
    },
    //搜索
    btnSearch() {
      if (this.search.keyword == "") {
        this.$message({
          title: "警告",
          message: "请输入关键字",
          type: "warning"
        })
        this.$refs.searchInput.focus()
        return
      }

      // 设置检索条件
      this.params = {
        searchType: this.search.type,
        searchValue: this.search.keyword
      }
    },
    //本地更新数据
    handleSuccess(data, mode) {
      if (mode == "add") {
        // this.$refs.table.tableData.unshift(data)
        this.$refs.table.getData()
      } else if (mode == "edit") {
        this.$refs.table.tableData
          .filter((item) => item.userId === data.userId)
          .forEach((item) => {
            Object.assign(item, data)
          })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.custom-tree-node {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  height: 100%;
  padding-right: 24px;
}
.custom-tree-node .label {
  display: flex;
  align-items: center;
  height: 100%;
}
.custom-tree-node .label .el-tag {
  margin-left: 5px;
}
.custom-tree-node .do {
  display: none;
}
.custom-tree-node .do i {
  margin-left: 5px;
  color: #999;
}
.custom-tree-node .do i:hover {
  color: #333;
}

.custom-tree-node:hover {
  color: #409eff;
}
.custom-tree-node:hover .do {
  display: inline-block;
  animation: fadeIn;
  animation-duration: 1s;
}

.orgChart{
  width: 100%;
  height: calc(100% - 30px); 
  font-size: 16px;
  text-align: right;
}
</style>
